<!--
  * 退款操作
  *
  * @Author:    zhoujk
  * @Date:      2025-01-26 06:40:44
-->
<template>
  <a-modal title="退款操作" :open="visibleFlag" @cancel="onClose" :maskClosable="false" :destroyOnClose="true" :width="500">
    <a-form ref="formRef" :model="form" :rules="rules" :label-col="5">
      <a-row>
        <a-col :span="2">
          <div class="confirm-content" style="margin-top: 5px">
            <span class="confirm-icon">
              <QuestionCircleOutlined style="color: #faad14; font-size: 22px" />
            </span>
          </div>
        </a-col>
        <a-col :span="22">
          <a-row>
            <a-col :span="12">
              <a-form-item style="margin-left: 5px" label="交易金额" name="tradeAmt">
                <a-input-number
                  type="text"
                  :formatter="(value) => amountFormatter(value)"
                  v-model:value="form.tradeAmt"
                  :bordered="false"
                  disabled
                  style="width: 95%; margin-bottom: 5px"
                />
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item label="已退款金额" name="refundAmt">
                <a-input-number
                  type="text"
                  :formatter="(value) => amountFormatter(value)"
                  v-model:value="form.refundAmt"
                  :bordered="false"
                  disabled
                  style="width: 95%; margin-bottom: 5px"
                />
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item style="margin-left: 5px" label="可退款金额" name="pleaseRefundAmt">
                <a-input-number
                  type="text"
                  :formatter="(value) => amountFormatter(value)"
                  v-model:value="form.pleaseRefundAmt"
                  :bordered="false"
                  disabled
                  style="width: 95%; margin-bottom: 5px"
                />
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item label="本次退款金额" name="onRefundAmt">
                <a-input-number
                  :min="0"
                  :max="form.pleaseRefundAmt / 100"
                  :precision="2"
                  style="width: 70%"
                  v-model:value="form.onRefundAmt"
                  addon-after="元"
                  placeholder="请输入退款金额"
                />
              </a-form-item>
            </a-col>
            <a-col :span="24">
              <a-form-item label="退款原因" name="reason">
                <a-textarea v-model:value="form.reason" :rows="3" placeholder="请输入退款原因，限80个汉字" :maxlength="80" showCount />
              </a-form-item>
            </a-col>
          </a-row>
        </a-col>
      </a-row>
    </a-form>
    <template #footer>
      <a-space>
        <a-button @click="onClose">取消</a-button>
        <a-button type="primary" @click="onSubmit">保存</a-button>
      </a-space>
    </template>
  </a-modal>
</template>
<script setup>
  import { computed, nextTick, reactive, ref } from 'vue'
  import _ from 'lodash'
  import { message } from 'ant-design-vue'
  import { SmartLoading } from '/@/components/framework/smart-loading'
  import { refundApi } from '/@/api/business/b-merchant/refund/refund-api'
  import { smartSentry } from '/@/lib/smart-sentry'
  import { QuestionCircleOutlined } from '@ant-design/icons-vue'
  import { ZZB_REFUND_STATUS_ENUM } from '/@/constants/business/b-pay/refund/refund-const.js'

  // ------------------------ 事件 ------------------------

  const emits = defineEmits(['reloadList'])
  const formRef = ref()

  // ------------------------ 显示与隐藏 ------------------------
  // 是否显示
  const visibleFlag = ref(false)

  function show(rowData) {
    Object.assign(form, formDefault)
    if (rowData && !_.isEmpty(rowData)) {
      Object.assign(form, rowData)
    }
    form.orderId = rowData.id
    form.pleaseRefundAmt = form.tradeAmt - form.refundAmt
    // 使用字典时把下面这注释修改成自己的字典字段 有多个字典字段就复制多份同理修改 不然打开表单时不显示字典初始值
    // if (form.status && form.status.length > 0) {
    //   form.status = form.status.map((e) => e.valueCode);
    // }
    visibleFlag.value = true
    nextTick(() => {
      formRef.value.clearValidate()
    })
  }

  function onClose() {
    Object.assign(form, formDefault)
    visibleFlag.value = false
  }

  // ------------------------ 表单 ------------------------

  const formDefault = {
    merchantId: undefined,
    orderId: undefined,
    tradeAmt: 0, // 交易金额
    refundAmt: 0, // 退款金额
    pleaseRefundAmt: 0, // 可退款金额
    onRefundAmt: 0, // 本次退款金额
    reason: undefined, // 退款原因
  }

  let form = reactive({ ...formDefault })

  const rules = computed(() => ({
    onRefundAmt: [
      { required: true, message: '本次退款金额必填' },
      {
        type: 'number',
        min: 0,
        max: form.pleaseRefundAmt / 100,
        message: `金额需在 0 ~ ${amountFormatter(form.pleaseRefundAmt)}  之间`,
        validator: (rule, value) => {
          if (value <= form.pleaseRefundAmt / 100) {
            return Promise.resolve()
          } else {
            return Promise.reject(new Error(rule.message))
          }
        },
        trigger: ['blur', 'change'],
      },
    ],
    reason: [{ required: true, message: '退款原因必填' }],
  }))

  // 点击确定，验证表单
  async function onSubmit() {
    try {
      await formRef.value.validate()
      save()
    } catch (err) {
      message.error('参数验证错误，请仔细填写表单数据!')
    }
  }

  // 新建、编辑API
  async function save() {
    SmartLoading.show()
    try {
      const res = await refundApi.submit({ ...form, onRefundAmt: (form.onRefundAmt * 100).toFixed(0) })
      if (ZZB_REFUND_STATUS_ENUM.REFUND_STATUS_ING.value === res.data.status) {
        message.success('操作成功')
      } else if (ZZB_REFUND_STATUS_ENUM.REFUND_STATUS_SUCCESS.value === res.data.status) {
        message.success('退款成功')
      } else {
        message.error('退款失败：' + res.data.errorMsg)
      }
      emits('reloadList')
      onClose()
    } catch (err) {
      smartSentry.captureError(err)
    } finally {
      SmartLoading.hide()
    }
  }

  const amountFormatter = (value) => {
    let val = value / 100
    // 1. 空值处理
    if (val == null || val === '') return '0.00\u00A0元'

    // 2. 统一转换为字符串处理（兼容科学计数法）
    let numStr = String(Number(val).toFixed(2)) // 强制保留两位小数

    // 3. 处理整数部分千分位
    const [integer, decimal] = numStr.split('.')
    const formattedInt = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',')

    // 4. 拼接结果（使用Unicode不间断空格）
    return `${formattedInt}.${decimal}\u00A0元`
  }

  defineExpose({
    show,
  })
</script>
